home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Language/OS - Multiplatform Resource Library
/
LANGUAGE OS.iso
/
escalant
/
escala21.lha
/
escalante2.1
/
src
/
vgm
/
VGraphElement.h
< prev
next >
Wrap
C/C++ Source or Header
|
1993-07-15
|
22KB
|
1,001 lines
//
// Copyright (C) 1993 Jeff McWhirter
//
#ifndef VGRAPHELEMENT_H
#define VGRAPHELEMENT_H
#include "EscalanteGlobal.h"
#include "PVGraphElement.h"
#include "CommonGfx.h"
#include "Point.h"
#include "Rectangle.h"
//
//Various global flags
//
extern bool gWriteOutGfx; //When doing IO do we write out theimage
extern bool gMoveHint; //Is the event eAEventMoveByHint active
extern bool gScaleHint; //Is the event eAEventScaleByHint active
extern bool gLCHint; //Are hint location constraints active
extern int gMaxEndPtHops; //How many hops do we go when looking for an endpoint
extern bool gDoLC; //Are all location constraints active
extern bool gPropagateMove; //Do we propagate position changes
extern bool gCopySGelt; //Do we make a copy of the sgelt when copying the vgelt
extern bool gKeepSGelt; //If a vgelt is copied and the selt wasn't
//do we keep the old sgelt
class GfxSet;
class Gfx;
class Rectangle;
class Line;
class TextGfx;
class VEntity;
class VRelation;
class PVRelation;
class VGraphElement;
class PointArray;
class ObjectGrid;
class TimerObject;
#ifdef USE_STRUCTURAL
class SRelation;
class SGraphElement;
extern VGraphElement * (*gFindPrototype)(SGraphElement *sg, VGraphElement * original, VGraphElement * graph);
#endif
typedef bool (*ElementOkFunc)(VGraphElement*);
extern ElementOkFunc gElementOkFunc;
extern void * gElementOkFuncData;
//
//These procedures are used as propagating functions to turn on(off) head(tail)
//of incident relaitons
//
bool HeadVisOff (VGraphElement*, VRelation*, VGraphElement*,void * ,int , bool & );
bool HeadVisOn (VGraphElement*, VRelation*, VGraphElement*,void * ,int , bool & );
bool TailVisOff (VGraphElement*, VRelation*, VGraphElement*,void * ,int , bool & );
bool TailVisOn (VGraphElement*, VRelation*, VGraphElement*,void * ,int , bool & );
//
//Same as above but use the bit in the relation, eShownFlag, to set the visibility
//
bool TurnOffHead(VGraphElement*root, VRelation* rel, VGraphElement* target);
bool TurnOnHead(VGraphElement*root, VRelation* rel, VGraphElement* target);
bool TurnOffTail(VGraphElement*root, VRelation* rel, VGraphElement* target);
bool TurnOnTail(VGraphElement*root, VRelation* rel, VGraphElement* target);
//
//These procedures are used as propagating functions to turn on(off) the gfx
//of the head(tail) of incident relations
//
bool HeadGfxOff (VGraphElement*, VRelation*, VGraphElement*,void * ,int , bool & );
bool HeadGfxOn (VGraphElement*, VRelation*, VGraphElement*,void * ,int , bool & );
bool TailGfxOff (VGraphElement*, VRelation*, VGraphElement*,void * ,int , bool & );
bool TailGfxOn (VGraphElement*, VRelation*, VGraphElement*,void * ,int , bool & );
//
//Propagate the scaling of elements
//
bool Scaler (VGraphElement*, VRelation*, VGraphElement*,void * ,int , bool & );
enum AddJointType{
eJointFirst,
eJointLast,
eJointClosest};
enum VGEFlags{
eVGEVisible = BIT(0),
eVGEBaseVisible = BIT(1),
eVGEBuffering = BIT(2),
eVGEInNewElement = BIT(3),
eVGEDrawOthers = BIT(4),
eVGEInSomething = BIT(5),
eVGEGoingToUpdate = BIT(6),
eVGEIbboxReference = BIT(7),
eVGEShowInPalette = BIT(8),
eVGEAcceptMapping = BIT(9),
eVGEInGetEndPt = BIT(10),
eVGEGfxChanged = BIT(11),
eRelativeJoints = BIT(12),
eNeedJoints = BIT(13),
eWriteGfx = BIT(14),
eAcceptPosChange = BIT(15),
eVGEMapWidth = BIT(16),
eVGEMapHeight = BIT(17),
eVGEMapArea = BIT(18),
eVGEMapNWX = BIT(19),
eVGEMapSEX = BIT(20),
eVGEMapNWY = BIT(21),
eVGEMapSEY = BIT(22),
eVGELast = 22,
eVGraphElementLast = ePVGraphElementLast,
};
VGraphElement * CloneElt(VGraphElement * oldvelt,
VGraphElement * vg,
Point dp = gPoint0);
#define BEGIN_VGE_GUARD(the_flag) if(!TestVGEFlag(the_flag)){ SetVGEFlag(the_flag,TRUE);
#define END_VGE_GUARD(the_flag) SetVGEFlag(the_flag,FALSE);}
#ifdef USE_STRUCTURAL
#define ALLVGELTS(velt,func,type) \
SGraphElement * sg =velt-> GetSGelt();\
if(!sg)return;\
if(!sg->vgelts)return;\
Iter next(sg->vgelts);\
register type * vwxy;\
while(vwxy = (type *) next())\
if(vwxy->IsKindOf(type))\
vwxy->func
#define ALLVGELTSPOS(velt,func,type) \
SGraphElement * sg =velt-> GetSGelt();\
if(!sg)return;\
if(!sg->vgelts)return;\
Iter next(sg->vgelts);\
register type * vwxy;\
while(vwxy = (type *) next())\
if(vwxy->IsKindOf(type))\
if(!(vwxy != velt && !vwxy->AcceptPosChange())) \
vwxy->func
#endif
#ifndef USE_STRUCTURAL
#define ALLVGELTS(velt,func,type) \
velt->func
#define ALLVGELTSPOS(velt,func,type) \
velt->func
#endif
#define BEGINLOOP(elt,ename,rname,dir) {\
if(elt->GetRelations(dir)){\
Iter eltloopiter(elt->GetRelations(dir));\
while(rname=(VRelation*)eltloopiter()) {\
ename = (VGraphElement*)rname->GetOtherElement(elt);
#define ENDLOOP }}}
#define VINOUT(element,rname,rtype,ename,etype) {\
Iter eltloopiter(element->GetRelations(eIn));\
for(int iii = 0;iii <2;iii++){\
if(iii == 1) eltloopiter.Reset(element->GetRelations(eOut));\
while(rname=(rtype*)eltloopiter()) \
if(rname->IsKindOf(rtype) && (ename = (etype*)rname->GetOtherElement((element))) && (ename->IsKindOf(etype))) {
#define ENDVINOUT }}}
#define VBEGINRLOOP(element,dir,rname,rtype,ename,etype) {\
if((element)->GetRelations(dir)){\
Iter eltloopiter((element)->GetRelations(dir));\
while(rname=(rtype*)eltloopiter()) \
if(rname->IsKindOf(rtype) && (ename = (etype*)rname->GetOtherElement((element))) && (ename->IsKindOf(etype))) {
#define VENDRLOOP }}}
#define VOUT(element,rname,rtype,ename,etype) VBEGINRLOOP(element,eOut,rname,rtype,ename,etype)
#define ENDVOUT VENDRLOOP
#define VOUTTHIS(rname,rtype,ename,etype) VBEGINRLOOP(this,eOut,rname,rtype,ename,etype)
#define ENDVOUTTHIS VENDRLOOP
#define VIN(element,rname,rtype,ename,etype) VBEGINRLOOP(element,eIn,rname,rtype,ename,etype)
#define ENDVIN VENDRLOOP
#define VINTHIS(rname,rtype,ename,etype) VBEGINRLOOP(this,eIn,rname,rtype,ename,etype)
#define ENDVINTHIS VENDRLOOP
#define VITERELTS(element,ename,rname) VBEGINRLOOP(element,eOut,rname,VMemberOf,ename,VGraphElement)
#define VENDITER VENDRLOOP
#define VGraphElement_BASE PVGraphElement
class VGraphElement : public VGraphElement_BASE {
public:
long int VGEFlag;
//
//p1 and p2 define the position and size of this element.
//joints are a list of other points
//The Gfx objects associated with this element, (contianed in theimage)
//get their position and sioze from these points
//
Point p1,p2;
PointArray * joints;
GfxSet * theimage;
//
//What views does this element draw itself and others in
//
ObjList * views;
//
//Corresponding SGraphElement
//
#ifdef USE_STRUCTURAL
SGraphElement * sgelt;
void RemoveSGelt();
void SetSGelt(SGraphElement * sg);
SGraphElement* GetSGelt(){return sgelt;}
virtual void InitSVAMap(){}
VGraphElement* FindVGelt(SGraphElement * sg);
bool OkToAddElement(SGraphElement * sg){return MS_OkToAddElement(sg);}
virtual bool MS_OkToAddElement(SGraphElement * ){return TRUE;}
//
//These methods are used when looking for a prototype element.
//They are called when the SGraphElement this element is
//associated with has added an element. The sgelt calls
//VGraphElement::NewElement(SGraphElement*sg). This element
//calls FindPrototype to see if there is a element in the protos
//list that has a sgelt of the same type of the sg argument to
//NewElement. If FindPrototype returns 0 then MS_FindPrototype
//is called. If that returns 0 then if the function ptr, gFindPrototype,
//is non-null than that is called. If that returns 0 then no element
//is added.
//
VGraphElement* FindPrototype(Class * sclass,Class * vclass =0);
VGraphElement* FindPrototype(SGraphElement * s = 0,VGraphElement * v = 0);
virtual VGraphElement* MS_FindPrototype(SGraphElement *sg, VGraphElement * original){
return 0;
}
//
//This is called by the sgelt when the sgelt has added an element
//
VGraphElement* NewElement(SGraphElement * s,
SRelation * sr = 0,
VGraphElement * original=0);
VGraphElement* NewElement(VGraphElement * velt,SGraphElement * selt){
return NewElement(velt,0,selt,0,velt);
}
//
//This is called when a new element is added directly to this element
//
VGraphElement* NewElement(VGraphElement * velt,VRelation * vrel=0,
SGraphElement * selt=0,
SRelation * srel=0,VGraphElement * original=0
);
#endif
#ifndef USE_STRUCTURAL
VGraphElement* NewElement(VGraphElement * velt,VRelation * vrel=0){AddElement(velt,vrel)}
#endif
//
//This is called when a set of elements are added directly to this element
//
void NewElement(class Set*);
//
//If this element is in a prototype list can it be used as a prototype
//when we get a NewElement from a connected SGraphElement.
//
bool AcceptMapping(){return TestVGEFlag(eVGEAcceptMapping);}
void AcceptMapping(bool b){SetVGEFlag(eVGEAcceptMapping,b);}
//
//Bounding box of any elements this element has an eIBBoxReference
//dependency with
//
#ifdef USE_IBBOX_REF
Rectangle ibbox;
#endif
MetaDef(VGraphElement);
VGraphElement();
~VGraphElement();
void Init();
void InitClone();
void InitAfterReading();
void InitAfterClone();
virtual ObjectGrid* GetGrid(){return 0;}
virtual TimerObject* GetTimer(){return 0;}
virtual void Tick(){}
void ResolvePtrNeeds();
void *DoEvent(Events event, PVGraphElement * elt =0, void * data=0);
//
//This returns a new relation of type VMemberOf. This is called when
//an element is added to this element
//
PVRelation * GetDefaultMemberOf();
void AddGroupRelation(PVRelation * );
//
//Access for the two pointsP1 and P2
//
void SetP1(Point p){p1 = p;SignalSizeChange();}
void SetP2(Point p){p2 = p; SignalSizeChange();}
void SetP1P2(Point pp1,Point pp2){p1 = pp1;p2 = pp2; SignalSizeChange();}
//
//This method returns the minimum extent of this element
//
virtual Point GetMinExtent(){return AsRect().extent;}
//
//When adding this element do we want to add a bunch of joints
//
bool NeedJoints(){return TestVGEFlag(eNeedJoints);}
void NeedJoints(bool b){SetVGEFlag(eNeedJoints,b);}
//
//When called by All... do we accept such a call
//
bool AcceptPosChange(){return TestVGEFlag(eAcceptPosChange);}
void AcceptPosChange(bool b){SetVGEFlag(eAcceptPosChange,b);}
//
//When writing out this object is theimage also written out
//Normally it isn't. IO seems to be quicker that way.
//Of course you can't save any state that has changes in the Gfx's
//
bool WriteGfx(){return TestVGEFlag(eWriteGfx);}
void WriteGfx(bool b){SetVGEFlag(eWriteGfx,b);}
//
//Are the joints that I have relative to the point p1
//
bool RelJoints(){return TestVGEFlag(eRelativeJoints);}
void RelJoints(bool b){SetVGEFlag(eRelativeJoints,b);}
//
//Mutliple access to the joints
//
void AllMoveJoint(Point p,int ix);
void AllMoveJointBy(Point p,int ix);
void AllAddJointAt(Point p, int ix);
void AllAddJointFirst(Point p);
void AllAddJointLast(Point p);
void AllAddJoint (Point p);
void AllAddJoint (Point p,AddJointType t);
//
//Catch the setting dead. If we get undead then update image and redraw
//
void SetDead(bool f);
void AllSetDead(bool b);
//
//A bunch of joint things
//
Point TransPoint(Point p){return p + (RelJoints()?p1:gPoint0);}
void MoveJoint(Point p,int ix);
void MoveJointBy(Point p,int ix);
void AddJoint (Point p);
void AddJoint (Point p,AddJointType t);
int IndexOfLocPt(LocPt lp);
void RemoveJoint(int ix);
void RemoveAllJoints();
void RemoveClosestJoint (Point p);
Point GetPointAlongLine(float perc);
void CheckJoints();
void AddJointAt(Point p, int ix);
void AddJointFirst(Point p);
void AddJointLast(Point p);
Point MiddlePoint();
int NumberOfJoints();
Point GetFirstJoint();
Point GetLastJoint();
int GetIndexAt(Point p);
Point GetJointAt(int at);
Point GetP1Less1();
Point GetP2Less1();
//
//Move a point on me defined by LP (e.g. cNM, cCenter)
//
void Reshape(Point, LocPt,bool both = FALSE);
void ReshapeBy(Point, LocPt,bool both = FALSE);
virtual void MoveBy(Point);
void MoveTo(Point);
//
//return the Rectangle formed by p1 and p2
//
Rectangle AsRect();
//
//return the Line formed by p1 and p2
//
Line AsLine();
Point GetOrigin(){return AsRect().origin;}
void SetOrigin(Point p, bool notify = TRUE);
void SetExtent(Point p, bool notify = TRUE);
void AllShrink();
void AllShrinkX();
void AllShrinkY();
void Shrink();
void ShrinkX();
void ShrinkY();
double Angle();
void RotateByRadian(double theta = 0.0);
void RotateByDegree(double degree = 0.0);
void RotateTo(Point p);
void Scale(float , float ,Point);
void Scale(float sx , float sy ){Scale(sx,sy,AsRect().Center());}
void Scale(float f1){Scale(f1,f1);}
void* GetAttribute(int aid,DataType & type);
void ChangeAttribute(int aid, void * data, DataType type);
AttrMap* MapAttribute(int external,
int internal,
Object * fromobj,
AttrFilter * af=0);
//
//VGraphElement has its own flags (we were running out
//of the ones the Object class provides
//
bool TestVGEFlag(int f){return TestMask(VGEFlag,f);}
void SetVGEFlag(int f,bool b){SetMask(VGEFlag,f,b);}
//
//Gets called by the View when this element is shown in a palette
//Returns the name of the bitmap file to be displayed
//
virtual char* GetIconName(){return "Node.im";}
//
//If this element is in a prototype list iun the view do
//we show it in the palette?
//
bool ShowInPalette(){return TestVGEFlag(eVGEShowInPalette);}
void ShowInPalette(bool b){SetVGEFlag(eVGEShowInPalette,b);}
//
//Flag to see when a Gfx has changed. We use this when we're
//buffering changes.
//
bool GfxChanged(){return TestVGEFlag(eVGEGfxChanged);}
void GfxChanged(bool b){SetVGEFlag(eVGEGfxChanged,b);}
//
//These are virtual methods defined in PVGraphElement
//We catch them here to see if the new relation contains
//any event dependencies or location constriants that affect us
//
void AddInRelation(PVRelation *);
void AddOutRelation(PVRelation *);
void NewTail(PVRelation * r, PVGraphElement * elt=0,PVGraphElement * oldtl=0);
void NewHead(PVRelation * r, PVGraphElement * elt=0,PVGraphElement * oldhd=0);
void RemoveOutRelation(PVRelation *r);
void RemoveInRelation(PVRelation *r);
//
//These methods let you turn on(off) the visibility of elements that this
//element draws
//
void SetEltVisibility(class Class * c,bool state,bool protosToo = TRUE, Object * view =0);
void SetEltVisibility(RDir dir,
bool state = FALSE,
class Class * relClass = 0,
class Class * eltClass = 0,
Object * view =0
);
//
//This method lets you get the bounding box of the elements this element draws
//
void GetElementBBox(Rectangle &r,Object * view =0);
void GetElementBBox2(Rectangle &r,Object * view =0);
//
//All of these methods let you find other elements. Either ones
//contained by soem rectangle or ones closest to a point.
//If you look in EscalanteView you can see how these are called
//
void FindElements2(Rectangle r,
Set & s,
class Class * c,
Object * v);
bool FindElements(Rectangle r,
Set & s,
class Class * c = 0,
Object * view =0);
void FindContainedElements2(Rectangle r,
Set & s,
class Class * c,
Object * v,
bool UseGfxIbbox = TRUE);
bool FindContainedElements(Rectangle r,
Set & s,
class Class * c = 0,
Object * view =0,
bool UseGfxIbbox = TRUE);
bool FindEntities( Rectangle r,Set & s,class Class * c = 0);
bool FindRelations( Rectangle r, Set & s,class Class * c = 0);
void FindClosest2(Point p,
VGraphElement * & elt,
Gfx * & gfx,
class Class * eltclass,
int gravity,
Object * view,
bool input = FALSE,
int *distance=0);
void FindClosest(Point p,
VGraphElement * & elt,
Gfx * & gfx,
class Class * eltclass=0,
int gravity = MAXINT,
Object * view = 0,
bool input = FALSE,
int *distance = 0);
VGraphElement* FindClosestElement(Point p,
class Class * c,
int gravity = MAXINT,
Object * view = 0);
VEntity* FindClosestEntity(Point p,
class Class * c = 0,
int gravity = MAXINT,
Object * view = 0);
VRelation* FindClosestRelation(Point p,
class Class * c = 0,
int gravity = MAXINT,
Object * view = 0);
Gfx* FindClosestGfx(Point p,
class Class * eltclass = 0,
int gravity = MAXINT,
Object * view = 0);
Gfx* FindClosestInputGfx(Point p,
class Class * eltclass = 0,
int gravity = MAXINT,
Object * view = 0);
//
//This finds elements that draw this element
//
VGraphElement* FindDrawer();
VGraphElement* FindDrawer(class Class* c);
void FindDrawers(Set & l);
//
//Move this element visually to the back(front).
//In essence switch the position of the relation that draws this element
//
void ToBack(){
VGraphElement * drawer = FindDrawer();
if(drawer) drawer->ToBack(this);
}
void ToFront(){
VGraphElement * drawer = FindDrawer();
if(drawer) drawer->ToFront(this);
}
//
//Move some element to the back(front)
//
void ToFront(VGraphElement * vg);
void ToBack(VGraphElement * vg);
//
//If we have stopped adding this element then
//act like it has moved so that it checks its image and
//tells other connected elements it has moved
//(a performance hack)
//
void SetAdding(bool b){
VGraphElement_BASE::SetAdding(b);
if(!b)Moved();
}
//
//Tell others this element has moved
//
void Moved(Events not= eEventNull,bool force = FALSE);
void ExternalMove();
void SendPositionChange(bool force = TRUE);
//
//When this element has moved call this. A hook.
//
virtual void MS_Moved(){}
void DoObserve(int , int , void * , Object *);
//
//Flags to squelch any broadcasts of position changes
//
bool GoingToUpdate(){return TestVGEFlag(eVGEGoingToUpdate);}
void GoingToUpdate(bool f){SetVGEFlag(eVGEGoingToUpdate,f);}
//
//A bunch of things for Location Constraints.
//
#ifdef USELC
ObjList * outlcs;
ObjList * inlcs;
void AddInLC(Object*);
void RemoveInLC(Object*);
void AddOutLC(Object*);
void RemoveOutLC(Object*);
bool FindLocDepSize(Point &np1, Point & np2);
void LCChanged();
#endif USELC
//
//Buffer position and image changes
//
void SetBuffering(bool b);
bool Buffering(){return TestVGEFlag(eVGEBuffering);}
//
//Access for various bounding boxes of this element
//
Rectangle GetIBBox();
Rectangle GetGfxIBBox();
bool ResetIBBox(bool force = FALSE);
void SetGfxVisibility(int id,bool state,
bool prop = FALSE,
bool protosToo = FALSE,
Object * view = 0);
void SetGfxVisibility2(int id,
bool state,
bool prop = FALSE,
bool protosToo = FALSE,
Object * view = 0);
void SetGfxVisibility(class Gfx * gfx,bool f);
void SetGfxVisibility(bool f, Set & s);
//
//Search through theimage to find a Gfx object with this id
//
Gfx * GetGfxWithId(int id);
//
//Tell theimage to reset itself
//
void ResetGfx();
//
//Force update of image and propagation of position change
//
void ForceSizeUpdate(){
SizeChanged();
MS_Moved();
Send(0,eNEventMoved,0);
PropagateEvent(eNEventMoved,eEventNull,this);
}
//
//Some position has changed so reset the image
//
bool SizeChanged(){
AdjustSize();
ResetGfx();
SendPositionChange();
return TRUE;
}
void SignalSizeChange(Events notevent= eEventNull);
//
//Check if our current position needs to be changed (e.g. because of a LC)
//
virtual bool AdjustSize();
//
//There has been a change in the dependencies of an incident relation
//
void DepChange(Events ,DepTypes);
//
//Are we visible
//
void ResetVisibility();
virtual bool GetVisibilityDep();
bool GetVisible() {return TestVGEFlag(eVGEVisible);}
void SetVisible(bool s);
//
//This element may draw other connected elements.
//This is determined by the event dependenies in the incident
//relations. For performance reasons we keep track of whether
//this element draws other elements
//
bool DrawOthers(){return TestVGEFlag(eVGEDrawOthers);}
void DrawOthers(bool b){SetVGEFlag(eVGEDrawOthers,b);}
//
//Draw this element
//
virtual void Draw(Rectangle r,void * v);
//
//Draw connected elements
//
void DrawAll(Rectangle r,void * v);
//
//A hook for drawing
//
virtual bool MS_Draw(Rectangle,void *){return TRUE;}
//
//Access to the views list
//
void AddView(Object*);
void RemoveView(Object*);
//
//Return the point that is defined by lp, (e.g. cNW,cCenter, etc.)
//
virtual bool GetLocPt(LocPt p, Point *p ,void * data = 0);
//
//Find the element that the relation rel should connect to.
//If this element is not visible then find a connected relation
//that has the eEndPtReference event set
//
VGraphElement* GetEndPointElt(VRelation * rel = 0, int maxhops = gMaxEndPtHops);
void SignalImageChange(Rectangle r,bool myChange = TRUE);
void GfxIBBoxChanged(Rectangle r);
Rectangle GetReferenceIBBox();
virtual void MakeImages();
virtual void MS_MakeImages(){}
//
//Call all of the vgraphelements connected to the sgelt of this element
//
void AllScale(float , float );
void AllScale(float );
void AllRotateByRadian(double theta = 0.0);
void AllRotateByDegree(double degree = 0.0);
void AllRotateTo(Point p);
void AllSetOrigin(Point p, bool notify = TRUE);
void AllSetExtent(Point p, bool notify = TRUE);
void AllSetP1(Point p);
void AllSetP2(Point p);
void AllMoveTo(Point);
void AllReshape(Point, LocPt, bool b=FALSE);
void AllReshapeBy(Point, LocPt, bool b=FALSE);
void AllMoveBy(Point p );
void AllSetVisible(bool s);
void AllSetGfxVisibility(int id,bool state, bool prop = FALSE,bool protosToo = FALSE);
void AllRemoveView(Object*);
void AllSetFlag(VGEFlags flag, bool f);
void AllSetVGEFlag(VGEFlags flag, bool f);
OStream& PrintOn(OStream&);
IStream& ReadFrom(IStream&);
};
void ShuffleElts(VGraphElement * vgraph, Rectangle r, int dir,ElementOkFunc =0);
void ShoveElts(VGraphElement * vgraph, Rectangle r,ElementOkFunc func =0);
void SuckElts(VGraphElement * vgraph, Rectangle r,ElementOkFunc func =0);
#endif VGraphElement_h